<?php
if( !defined('__ROOT__') ) die('Access denied');
class Model extends Core{

	private $db = NULL;
	private $opts = array();
	private $result = NULL;
	private $table = NULL;
	protected $error = false;
	public $dbPrefix = '';

	public function __construct($table=''){
		global $CONFIGS;
		if( isset($CONFIGS['dbPrefix']) ) $this->dbPrefix = $CONFIGS['dbPrefix'];
		$this->db = DB::init($CONFIGS);
		$this->get_table($table);
	}

	public function __call($method, $args){
		$arrOpts = array('field','where','value','order','limit','group','table');
		if( in_array($method, $arrOpts) ){
			if( $method=='table' && $this->dbPrefix ){
				$this->opts[$method] = $this->dbPrefix.$args[0];
			}else{
				$this->opts[$method] = $args[0];
			}
		}
		return $this;
	}

	private function parseOpts($opts=""){
		$return = array();
		if( $opts!="" ){
			$this->opts = $opts;
		}
		if( is_string($this->opts['field']) ){
			$return['field'] = $this->opts['field'];
		} elseif ( is_array($this->opts['field']) ) {
			$field = implode($this->opts['field'],',');
			$return['field'] = '`'.str_replace(',',"`,`",$field).'`';
		}else{
			$return['field'] = '*';
		}
		unset($this->opts['field']);

		if( $this->opts['where'] && is_string($this->opts['where']) ){
			$return['where'] = $this->opts['where'];
		} elseif( is_array($this->opts['where']) ){
			$logic = $this->opts['where']['_logic'] ? $this->opts['where']['_logic'] : 'AND';
			$opera = $this->opts['where']['_op'] ? $this->opts['where']['_op'] : '=';
			foreach( $this->opts['where'] as $k=>$v ){
				$where .= " `$k` $opera '$v' $logic";
			}
			$return['where'] = trim($where,$logic);	
		} else {
			$return['where'] = '1';
		}
		unset($this->opts['where']);
		
		$columns = $this->get_columns();
		if( $this->opts['value'] && is_array($this->opts['value']) ){
			$set = '';
			foreach($this->opts['value'] as $k=>$v){
				if( isset($columns[$k]) ) $k=$columns[$k];
				if( in_array($k,$columns) ){
					$v = $v===NULL ? 'NULL' : "'".$v."'";
					$set .= "`$k`=".$v.",";
				}
			}
			$return['value'] = trim($set,',');
		} else {
			$return['value'] = $this->opts['value'];
		}	
		unset($this->opts['value']);

		if( $this->opts['order'] && is_string($this->opts['order']) ){
			$return['order'] = $this->opts['order'];
			unset($this->opts['order']);
		}

		if( $this->opts['limit'] ){
			$return['limit'] = $this->opts['limit'];
			unset($this->opts['limit']);
		}

		if( $this->opts['group'] && is_string($this->opts['group']) ){
			$return['group'] = $this->opts['group'];
			unset($this->opts['group']);
		}

		return $return;
	}

	public function get_table( $tableName ){
		if( !empty($tableName) ){
			$this->opts['table'] = empty($this->dbPrefix) ? $tableName : $this->dbPrefix.$tableName;
		}
		return $this->opts['table'];	
	}

	public function query( $sql="" ){
		if( !empty($sql) ){
			$this->sql = $sql;
		}
		$this->result = $this->db->query( $this->sql );
		return $this->result;
	}

	public function get(){
		if( empty($this->result) ){
			$opts = $this->parseOpts();	
			$this->sql = 'SELECT '.$opts['field'].' FROM '.$this->opts['table'].' WHERE '.$opts['where'];
			if( isset($opts['group']) ){
				$this->sql .= ' GROUP BY '.$opts['group'];
			}
			if( isset($opts['order']) ){
				$this->sql .= ' ORDER BY '.$opts['order'];
			}
			if( isset($opts['limit']) ){
				$this->sql .= ' LIMIT '.$opts['limit'];
			}
			$this->query();
		}
		if( $this->result ){
			$return = array();
			while( $row = $this->db->fetch($this->result,1) ){
				$return[] = $row;
			}
			return $return;
		}else{
			return false;
		}
	}

	public function get_one(){
		if( empty($this->result) ){
			$opts = $this->parseOpts();	
			$this->sql = 'SELECT '.$opts['field'].' FROM `'.$this->opts['table'].'` WHERE '.$opts['where'];
			if( isset($opts['group']) ){
				$this->sql .= ' GROUP BY '.$opts['group'];
			}
			if( isset($opts['order']) ){
				$this->sql .= ' ORDER BY '.$opts['order'];
			}
			$this->sql .= ' LIMIT 0,1';
			$this->query();
		}
		if( $this->result ){
			return $this->db->fetch($this->result,1);
		}else{
			return false;
		}
	}

	/*public function get_view($viewname){
		$opts = $this->parseOpts($this->opts);	
		$file = __VIEW__.$viewname.'.view.php';
		if( !file_exists($file) ){
			return false;
		}
		$view = include_once($file);
		if( count($view)<2 ){
			return -3;
		}
		$sys_fields = array('_as','_on','_join');
		$fields = "";
		$from = "";
		foreach( $view as $k=>$v ){
			foreach( $sys_fields as $t ){
				if( isset($v[$t]) ){
					$key = substr($t,1);
					$$key = $v[$t];
					unset($v[$t]);
				}
			}
			if( empty($as) ){
				$as = strtoupper($k);
			}
			$from .= $this->get_table($k)." $as";
			if( !empty($on) ){
				$from .= " ON $on";
			}
			if( !empty($join) ){
				$from .= " $join ";
			}

			if( count($v)<1 ){
				$v = $this->get_columns($k);
			}
			
			foreach( $v as $real_field=>$map_field ){
				if( is_numeric($real_field) ){
					$fields .= ",$as.`$map_field`";
				}else{
					$fields .= ",$as.`$real_field` AS $map_field";
				}
			}		
			foreach( $sys_fields as $t ){
				$key = substr($t,1);
				if( isset($$key) ){
					unset($$key);	
				}
			}
		}
		$sql = "SELECT ".substr($fields,1)." FROM $from WHERE ".$opts['where'];

		if( isset($opts['group']) ){
			$sql .= ' GROUP BY '.$opts['group'];
		}
		if( isset($opts['order']) ){
			$sql .= ' ORDER BY '.$opts['order'];
		}
		if( isset($opts['limit']) ){
			$sql .= ' LIMIT '.$opts['limit'];
		}
		$this->sql = $sql;
		$this->query();
		if( !empty($this->result) ){
			$return = array();
			while( $row = $this->db->fetch($this->result,1) ){
				$return[] = $row;
			}
			return $return;
		}else{
			return false;
		}
	}*/

	public function count(){
		if( empty($this->result) ){
			$opts = $this->parseOpts();	
			$this->sql = 'SELECT COUNT(1) as num FROM '.$this->opts['table'].' WHERE '.$opts['where'];
			if( isset($opts['group']) ){
				$this->sql .= ' GROUP BY '.$opts['group'];
			}
			if( isset($opts['order']) ){
				$this->sql .= ' ORDER BY '.$opts['order'];
			}
			$this->query();
		}
		if( !empty($this->result) ){
			$return = array();
			while( $row = $this->db->fetch($this->result,1) ){
				$return = $row['num'];
			}
			$this->free_result();
			return $return;
		}else{
			return false;
		}
	}

	public function insert(){
		$opts = $this->parseOpts();
		$this->sql = 'INSERT INTO `'.$this->opts['table'].'` SET '.$opts['value'];
		$rs = $this->query();
		if( !$rs ) return false;
		$insertId = $this->db->insert_id();
		if ( $insertId ) return $insertId;
		return $rs;
	}

	public function delete(){
		$opts = $this->parseOpts();
		if( !isset($opts['where']) ){
			// 无条件的删除操作时返回
			return -1;
		}
		$this->sql = 'DELETE FROM `'.$this->opts['table'].'` WHERE '.$opts['where'];
		if( isset($opts['group']) ){
			$this->sql .= ' GROUP BY '.$opts['group'];
		}
		if( isset($opts['order']) ){
			$this->sql .= ' ORDER BY '.$opts['order'];
		}
		if( isset($opts['limit']) ){
			$this->sql .= ' LIMIT '.$opts['limit'];
		}
		$rs = $this->query();
		if( !empty($rs) ){
			return $this->db->affected_rows();
		}else{
			return NULL;
		}
	}

	public function update(){
		$opts = $this->parseOpts();
		$this->sql = 'UPDATE `'.$this->opts['table'].'` SET '.$opts['value'].' WHERE '.$opts['where'];
		if( isset($opts['group']) ){
			$this->sql .= ' GROUP BY '.$opts['group'];
		}
		if( isset($opts['order']) ){
			$this->sql .= ' ORDER BY '.$opts['order'];
		}
		if( isset($opts['limit']) ){
			$this->sql .= ' LIMIT '.$opts['limit'];
		}
		$rs = $this->query();
		if( $rs ){
			return $this->db->affected_rows();
		}else{
			return $rs;
		}
	}

	public function replace(){
		$opts = $this->parseOpts();
		$this->sql = 'REPLACE INTO `'.$this->opts['table'].'` SET '.$opts['value'];
		$rs = $this->query();
		if( $rs ){
			return $this->db->affected_rows();
		}else{
			return $rs;
		}
	}

	public function free_result(){
		unset($this->result);
	}

	public function get_columns(){
		if( empty($this->opts['table']) ){
			return NULL;
		}
		if( file_exists(__TABLE__.$this->opts['table'].'.php') ){
			$arr = include_once(__TABLE__.$this->opts['table'].'.php');
			return $arr;
		}
		$this->sql = 'SHOW COLUMNS FROM '.$this->opts['table'];
		$rs = $this->query();
		while( $row = $this->db->fetch($rs) ){
			$arr[] = $row['Field'];	
		}
		return $arr;
	}

	public function get_sql(){
		return $this->db->get_sql();
	}

	public function get_error(){
		if( $this->error ) return $this->error;
		return $this->db->error();
	}

	public function error($msg, $return="false"){
		$this->error = $msg;	
		return $return;
	}

}
